package coupon

import (
	sqlc "bp/db/sqlc"
	"bp/internal/render"
	"bp/internal/service/entity/coupon"
	"bp/internal/util"
	couponGrpc "bp/rpc/gen/webapi/coupon"
	"context"
)

// CreateCoupon 新建优惠券
func (s *CouponWebApiImp) CreateCoupon(ctx context.Context, req *couponGrpc.CreateCouponReq) (res *couponGrpc.CreateCouponRes, err error) {
	slog := util.NewContextLogger(ctx, s.slog)
	slog.Infof("coupon_imp_cmd.CreateCoupon=>%+v", req)
	defer render.FriendlyEntityError(&err, EntityName)
	res = &couponGrpc.CreateCouponRes{}

	var couponPtr *sqlc.Coupon
	var conv CouponPtrEntityToPbFunc
	err = s.dao.NewTxRunner().SqlcExecTx(ctx, func(q *sqlc.Queries) (err error) {
		createCouponParamPtr, itemCategoryConfPtrs, itemConfPtrs, err := s.VldCreateCouponReq(ctx, q, req)
		if err != nil {
			return
		}
		couponPtr, err = s.entityHub.CouponService.CreateCoupon(ctx, q, createCouponParamPtr)
		if err != nil {
			return
		}
		err = s.entityHub.CouponService.SetCouponItemCategories(ctx, q, &coupon.SetCouponItemCategoriesParam{
			CouponPtr:            couponPtr,
			ItemCategoryConfPtrs: itemCategoryConfPtrs,
		})
		if err != nil {
			return
		}
		err = s.entityHub.CouponService.SetCouponItems(ctx, q, &coupon.SetCouponItemsParam{
			CouponPtr:    couponPtr,
			ItemConfPtrs: itemConfPtrs,
		})
		if err != nil {
			return
		}
		_, err = s.entityHub.CouponService.EnsureCouponStat(ctx, q, false, &coupon.EnsureCouponStatParam{
			CouponPtr: couponPtr,
		})
		if err != nil {
			return
		}
		conv = s.ConvCouponPtrEntityToPb(itemCategoryConfPtrs, itemConfPtrs)
		slog.Infof("新建优惠券 ok")
		return
	})
	if err != nil {
		return
	}

	res.Coupon = conv(couponPtr)
	return
}

// UpdateCoupon 更新优惠券
func (s *CouponWebApiImp) UpdateCoupon(ctx context.Context, req *couponGrpc.UpdateCouponReq) (res *couponGrpc.UpdateCouponRes, err error) {
	slog := util.NewContextLogger(ctx, s.slog)
	slog.Infof("coupon_imp/cmd.UpdateCoupon=>%+v", req)
	defer render.FriendlyEntityError(&err, EntityName)
	res = &couponGrpc.UpdateCouponRes{}

	var couponPtr *sqlc.Coupon
	var conv CouponPtrEntityToPbFunc
	err = s.dao.NewTxRunner().SqlcExecTx(ctx, func(q *sqlc.Queries) (err error) {
		updateCouponParamPtr, itemCategoryConfPtrs, itemConfPtrs, err := s.VldUpdateCouponReq(ctx, q, req)
		if err != nil {
			return
		}
		couponPtr, err = s.entityHub.CouponService.UpdateCoupon(ctx, q, updateCouponParamPtr)
		if err != nil {
			return
		}
		err = s.entityHub.CouponService.SetCouponItemCategories(ctx, q, &coupon.SetCouponItemCategoriesParam{
			CouponPtr:            couponPtr,
			ItemCategoryConfPtrs: itemCategoryConfPtrs,
		})
		if err != nil {
			return
		}
		err = s.entityHub.CouponService.SetCouponItems(ctx, q, &coupon.SetCouponItemsParam{
			CouponPtr:    couponPtr,
			ItemConfPtrs: itemConfPtrs,
		})
		if err != nil {
			return
		}
		conv = s.ConvCouponPtrEntityToPb(itemCategoryConfPtrs, itemConfPtrs)
		slog.Infof("更新优惠券 ok")
		return
	})
	if err != nil {
		return
	}

	res.Coupon = conv(couponPtr)
	return
}

// PublishCoupon 发布优惠券
func (s *CouponWebApiImp) PublishCoupon(ctx context.Context, req *couponGrpc.PublishCouponReq) (res *couponGrpc.PublishCouponRes, err error) {
	slog := util.NewContextLogger(ctx, s.slog)
	slog.Infof("coupon_imp/cmd.PublishCoupon=>%+v", req)
	defer render.FriendlyEntityError(&err, EntityName)
	res = &couponGrpc.PublishCouponRes{}

	var couponPtr *sqlc.Coupon
	err = s.dao.NewTxRunner().SqlcExecTx(ctx, func(q *sqlc.Queries) (err error) {
		publishCouponParamPtr, err := s.VldPublishCouponReq(ctx, q, req)
		if err != nil {
			return
		}
		couponPtr, err = s.entityHub.CouponService.PublishCoupon(ctx, q, publishCouponParamPtr)
		if err != nil {
			return
		}
		slog.Infof("发布优惠券 ok")
		return
	})
	if err != nil {
		return
	}

	res.CouponStatus = couponPtr.CouponStatus
	return
}

// PauseCoupon 暂停优惠券
func (s *CouponWebApiImp) PauseCoupon(ctx context.Context, req *couponGrpc.PauseCouponReq) (res *couponGrpc.PauseCouponRes, err error) {
	slog := util.NewContextLogger(ctx, s.slog)
	slog.Infof("coupon_imp/cmd.PauseCoupon=>%+v", req)
	defer render.FriendlyEntityError(&err, EntityName)
	res = &couponGrpc.PauseCouponRes{}

	var couponPtr *sqlc.Coupon
	err = s.dao.NewTxRunner().SqlcExecTx(ctx, func(q *sqlc.Queries) (err error) {
		pauseCouponParamPtr, err := s.VldPauseCouponReq(ctx, q, req)
		if err != nil {
			return
		}
		couponPtr, err = s.entityHub.CouponService.PauseCoupon(ctx, q, pauseCouponParamPtr)
		if err != nil {
			return
		}
		slog.Infof("暂停优惠券 ok")
		return
	})
	if err != nil {
		return
	}

	res.CouponStatus = couponPtr.CouponStatus
	return
}

// ResumeCoupon 恢复优惠券
func (s *CouponWebApiImp) ResumeCoupon(ctx context.Context, req *couponGrpc.ResumeCouponReq) (res *couponGrpc.ResumeCouponRes, err error) {
	slog := util.NewContextLogger(ctx, s.slog)
	slog.Infof("coupon_imp/cmd.ResumeCoupon=>%+v", req)
	defer render.FriendlyEntityError(&err, EntityName)
	res = &couponGrpc.ResumeCouponRes{}

	var couponPtr *sqlc.Coupon
	err = s.dao.NewTxRunner().SqlcExecTx(ctx, func(q *sqlc.Queries) (err error) {
		resumeCouponParamPtr, err := s.VldResumeCouponReq(ctx, q, req)
		if err != nil {
			return
		}
		couponPtr, err = s.entityHub.CouponService.ResumeCoupon(ctx, q, resumeCouponParamPtr)
		if err != nil {
			return
		}
		slog.Infof("恢复优惠券 ok")
		return
	})
	if err != nil {
		return
	}

	res.CouponStatus = couponPtr.CouponStatus
	return
}
